# -*- coding: utf-8 -*-
import socket

class GPIB(object):

    def __init__(self, ui):
        """
            Construtor da classe.
        """
        self.ui = ui
        self.ipAddr = None
        self.gpibAddr = None



    def connect(self, ipAddr):
        """
            Conecta a interface GPIB
        """
        try:
            port = 1234
            self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.sock.connect((ipAddr, port))
        except socket.error :
            raise RuntimeError
        self.sock.settimeout(0.5)
        self.sock.sendall('++mode 1\n')
        self.sock.sendall('++auto 0\n')
        self.sock.sendall('++eos 3\n')
        self.sock.sendall('++eoi 1\n')
        self.sock.sendall('++eot_enable 1\n')
        self.sock.sendall('++eot_char 23\n')



    def closeConnection(self):
        """
            Desconecta a interface GPIB
        """
        self.sock.close()



    def settimeout(self, timeout):
        """
            Set read timeout in seconds
        """
        self.sock.settimeout(timeout)
        self._timeout = timeout



    def flush(self):
        """
            Clear any read buffers out
        """
        self.settimeout(0.1)
        line = self._read()
        result = ""
        while line != None:
            result += line
            line = self._read()
        self.sock.settimeout(self._timeout)
        return result



    def select(self, gpibAddr):
        """
            Seleciona o endereço GPIB
        """
        self.gpibAddr = gpibAddr
        self._write('++addr %d\n' % self.gpibAddr)



    def read(self):
        """
            Funcao para leitura
        """
        if self.gpibAddr == None:
            raise RuntimeError(
                                "GPIB address must select()ed before read()"
                                "is called\n")
        self._write("++read eoi\n")
        return self._read()



    def write(self, line):
        """
            Funcao para escrita 
        """
        if self.gpibAddr == None:
            raise RuntimeError(
                                "GPIB address must select()ed before read()"
                                "is called\n")
        # escape +, \n, \r, and \27 (ESC) chars
        line = line.replace('\x1B', '\x1B\x1B')
        line = line.replace('\n', '\x1B\n')
        line = line.replace('\r', '\x1B\r')
        line = line.replace('+', '\x1B+')
        self._write(line + "\n")



    def readPlot(self):
        """
            Funcao para adquirir plot 
        """
        self.ui.progressBar.setValue(30)
        sock = self.sock
        sock.settimeout(10.0)
        self.ui.progressBar.text()
        n = 5
        eot = "PG"
        msg = ""
        while True :
            self.ui.progressBar.setValue(n * 10)
            n += 1
            msg += sock.recv(1024)
            end = msg.find(eot)
            if end != -1:
                self.ui.progressBar.setValue(100)
                return msg



    def _read(self, eot = "\x17"):
        """
            Funcao interna para leitura
        """
        sock = self.sock
        msg = ""
        try:
            while True:
                msg += sock.recv(1024)
                end = msg.find(eot)
                if end == len(msg) - 1:
                    return msg[0:end - 1]
                elif end != -1:
                    print (
                            "warning, dropping %d byte tail of message."
                            "Tail='%s'" % (len(msg) - end, msg[end:]))
                    return msg[0:end - 1]
        except socket.timeout:
            if len(msg) > 0:
                raise RuntimeError(
                                    "Got timeout after receiving partial"
                                    "result : %s" % msg)
            else:
                return None



    def _write(self, line):
        """
            Funcao interna para escrita
        """
        self.sock.sendall(line)

